//工具生成，请不要手动修改...
//工具生成，请不要手动修改...
let r: any, Coder: any, SVT: any;
/** 传入k-coder来进行初始化 */
export function initXlsx(kcoder: any) {
    r = new kcoder.BinaryReader();
    Coder = kcoder.StructCoder;
    SVT = kcoder.StructValueType;
}

/** 表数量 */
export const xlsxCount = 5;
/** 表对象 */
export const Xlsx = {} as IXlsx;
/** 已加载的表 */
export const loadedDic: any = {};
const dataDic: any = {};
const clsDic: any = {};
/** 读取表数据 */
export function loadData(buf: Uint8Array, onCount?: (count: number) => void, onReload?: (reloadDic: { [name: string]: IXlsx[keyof IXlsx] }) => void) {
    let c = 0;
    r.start(buf);
    let reloadDic = Object.assign({}, loadedDic);
    while (r.hasNext) {
        let name = r.str;
        let md5 = r.str;
        let isCfg = r.byte;
        let data = r.cut(r.uint);
        let loaded = loadedDic[name];
        if (loaded && loaded.$md5 === md5) delete reloadDic[name];
        else {
            dataDic[name] = data;
            Object.defineProperty(Xlsx, name, {
                get: () => loadedDic[name] = (Object.defineProperty(Xlsx, name, {
                    value: load(name, md5, isCfg),
                    enumerable: true,
                    configurable: true
                }) as any)[name],
                enumerable: true,
                configurable: true
            });
        }
        onCount && onCount(++c);
    }
    for (let name in reloadDic) (Xlsx as any)[name];
    r.end();
    onReload && onReload(reloadDic);
}

function load(name: string, md5: string, isCfg: boolean) {
    r.start(dataDic[name]);
    delete dataDic[name];
    let Cls: any;
    if (!isCfg) {
        Cls = clsDic[name] ||= function () { };
        Cls.$name = Cls.prototype.$name = name;
        Cls.$md5 = md5;
        Cls.mergeDic = {};
        Cls.vos = [];
        Cls.voDic ||= {};
        Cls.get ||= (id: any) => Cls.voDic[id];
    }
    let fieldLen = r.uint;
    let struct: any[] = [];
    let getId: any;
    let mergeCoders: any[] = [];
    for (let i = fieldLen; --i >= 0;) {
        let fieldName = r.str;
        let svt = r.byte;
        let arrVec = r.uint;
        let param = r.uint;
        if (isCfg) {
            struct.push([fieldName, svt, arrVec, param]);
        } else {
            if (fieldName === "id") {
                switch (svt) {
                    case SVT.int: getId = () => r.int; break;
                    case SVT.uint: getId = () => r.uint; break;
                    case SVT.long: getId = () => r.long; break;
                    case SVT.ulong: getId = () => r.ulong; break;
                    case SVT.str: getId = () => r.str; break;
                }
            } else if (svt < SVT.str && arrVec <= 0) {
                struct.push([fieldName, svt, arrVec, param]);
            } else {
                let merge: any = Cls.mergeDic[fieldName] = {};
                Object.defineProperty(Cls.prototype, fieldName, {
                    get: function () { return merge.dataArr[merge.idxArr[this.$idx]] },
                    enumerable: true,
                    configurable: true
                });
                mergeCoders.push({ fieldName, coder: new Coder([["dataArr", svt, arrVec + 1, param], ["idxArr", SVT.uint, 1]]) });
            }
        }
    }
    let coder = new Coder(struct);
    if (isCfg) {
        let vo = coder.decode(r);
        vo.$name = name;
        vo.$md5 = md5;
        return vo;
    }
    let voLen = r.uint;
    let voDic: any = {};
    for (let i = 0; i < voLen; ++i) {
        let id = getId();
        Cls.vos.push(voDic[id] = (Cls.voDic[id] || new Cls()));
        voDic[id].id = id;
        voDic[id].$idx = i;
        coder.decode(r, voDic[id]);
    }
    Cls.voDic = voDic;
    for (let i = 0; i < mergeCoders.length; ++i) {
        let { fieldName, coder } = mergeCoders[i];
        let merge = Cls.mergeDic[fieldName];
        coder.decode(r, merge);
        merge.dataArr.unshift(undefined);
    }
    return Cls;
}

export interface N {
    /** 表名 */
    readonly $name: string;
}

export interface Xlsx<T> extends N {
    /** 数据列表 */
    readonly vos: T[];
    /** 通过id获取行数据 */
    get: (id: number | string) => T;
}

export interface IXlsx {
    /** [career.xlsx] */
    readonly career: Xlsx<XlsxVo.career>;
    /** [com.xlsx] */
    readonly com: XlsxVo.com;
    /** [map.xlsx] */
    readonly map: Xlsx<XlsxVo.map>;
    /** [str.xlsx] */
    readonly str: Xlsx<XlsxVo.str>;
    /** [view.xlsx] */
    readonly view: Xlsx<XlsxVo.view>;
}

/** 表vo结构 */
export namespace XlsxVo {

    /** [career.xlsx] */
    export interface career extends N {
        /** 职业ID */
        readonly id: number;
        /** 职业名 */
        readonly name: string;
        /** 职业介绍 */
        readonly desc: string;
    }

    /** [com.xlsx] */
    export interface com extends N {
        /** gate地址 */
        readonly gateHost: string;
    }

    /** [map.xlsx] */
    export interface map extends N {
        /** 地图id */
        readonly id: number;
        /** 地图字段 */
        readonly field: string;
        /** 地图名 */
        readonly name: string;
        /** 地图宽高 */
        readonly size: number[];
        /** 灯塔宽高 */
        readonly towerSize: number[];
        /** 视野观察宽高 */
        readonly watchSize: number[];
        /** 出生点列表 */
        readonly spawnPos: number[][];
        /** 底图路径 */
        readonly bgPic: string;
    }

    /** [str.xlsx] */
    export interface str extends N {
        /** 唯一ID */
        readonly id: string;
        /** 文本内容 */
        readonly str: string;
    }

    /** [view.xlsx] */
    export interface view extends N {
        /** 界面类名 */
        readonly id: string;
        /** 界面层级 */
        readonly layer: number;
    }

}